(function (global, factory) {
    // global：在浏览器/webpack环境中运行JQ，global->window；在NodeJS中运行JQ，global->this；
    "use strict";
    if (typeof module === "object" && typeof module.exports === "object") {
        // 当前运行JQ的环境是：NodeJS或者webpack「支持CommonJS模块规范」
        module.exports = global.document ?
            // global是window，也就是运行JQ的环境是webpack
            factory(global, true) :
            // 运行JQ的环境是NodeJS「JQ不支持在NodeJS环境下运行」
            function (w) {
                if (!w.document) {
                    throw new Error("jQuery requires a window with a document");
                }
                return factory(w);
            };
    } else {
        // 当前运行JQ的环境是：浏览器
        factory(global);
    }
})(
    // typeof检测一个未被声明的变量，不会抱错，值是“undefined”
    typeof window !== "undefined" ? window : this,
    // JQ核心函数
    function (window, noGlobal) {
        /*
         当JQ运行在浏览器环境下：window -> window全局对象 、 noGlobal -> undefined
            <script src='js/jquery.min.js'></script>
            ----
            $ -> jQuery
            jQuery -> jQuery

         当JQ运行在webpack环境下：window -> window全局对象 、 noGlobal -> true  把此函数执行的返回值，最后基于 module.exports 导出！！
            module.exports = jQuery;
            ----
            import $ from 'jquery'
            $ -> jQuery
            ----
            let $ = require('jquery')
            $ -> jQuery
         */
        var jQuery = function (selector, context) {
            // ...
        };

        /* 暴露API */
        // 让其支持AMD模块规范
        if (typeof define === "function" && define.amd) {
            define("jquery", [], function () {
                return jQuery;
            });
        }
        // 在浏览器环境下运行JQ：给全局对象中设置 jQuery/$ 属性，属性值就是 jQuery 函数！
        if (typeof noGlobal === "undefined") {
            window.jQuery = window.$ = jQuery;
        }
        // 在webpack环境下运行JQ
        return jQuery;
    }
);

/*
 ES模块规范：import、export、export default...
 CommonJS模块规范：require、module.exports...
 ----
 JS代码可以运行的环境：
   + 浏览器
     具备window全局对象 ：typeof window===“object”
     可以使用ES6Module（简称ES）模块规范，但是不支持CommonJS模块规范
   + NodeJS
     全局对象是global，没有window对象：typeof window===“undefined”
     支持的是CommonJS模块规范，但是不支持ES模块规范
   + webpack 
     原理：基于NodeJS实现模块的打包，最后把打包后的内容部署到服务器，交给浏览器运行
     具备window全局对象
     支持ES模块规范和CommonJS模块规范，而且可以让两者混淆使用
 */